package cn.hanyx.coder.design.pattern.behavioral.state.demo02;

import static cn.hanyx.coder.design.pattern.behavioral.state.demo02.State.*;

/**
 * MarioStateMachine
 * <p>
 * 状态机实现方式二：查表法
 * <p>
 * 对于状态很多、状态转移比较复杂的状态机来说，查表法比较合适。
 * 通过二维数组来表示状态转移图，能极大地提高代码的可读性和可维护性
 *
 * 像游戏
 * @author hanyx
 * @date 2020/06/08
 */
public class MarioStateMachine {
    private int score;
    private State currentState;

    public MarioStateMachine() {
        score = 0;
        currentState = State.SMALL;
    }

    private static final State[][] transitionTable = {
            {SUPER, CAPE, FIRE, DIE},
            {SUPER, CAPE, FIRE, SMALL},
            {CAPE, CAPE, FIRE, SMALL},
            {FIRE, CAPE, FIRE, SMALL}
    };

    private static final int[][] actionTable = {
            {100, 200, 200, -100},
            {100, 200, 200, -100},
            {100, 200, 200, -100},
            {100, 200, 200, -100}
    };

    /**
     * 碰到蘑菇
     */
    public void obtainMushRoom() {
        executeEvent(Event.GOT_MUSHROOM);
    }

    /**
     * 碰到斗篷
     */
    public void obtainCape() {
        executeEvent(Event.GOT_CAPE);
    }

    /**
     * 获得火焰
     */
    public void obtainFireFlower() {
        executeEvent(Event.GOT_FIRE);
    }

    /**
     * 碰到怪物
     */
    public void meetMonster() {
        executeEvent(Event.MET_MONSTER);
    }

    private void executeEvent(Event event) {
        int stateValue = currentState.getValue();
        int eventValue = event.getValue();
        currentState = transitionTable[stateValue][eventValue];
        score += actionTable[stateValue][eventValue];
    }

    public int getScore() {
        return score;
    }

    public State getCurrentState() {
        return currentState;
    }
}
